package com.infore.common.fw;


import com.infore.common.enums.BaseError;
import com.infore.common.exception.MyException;
import com.infore.common.response.ApiResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.sql.SQLException;
import java.sql.SQLSyntaxErrorException;


/**
 * @ControllerAdvice 和 @RestControllerAdvice都是对Controller和RestController进行增强的，可以全局捕获spring mvc抛的异常。
 * 这样我们的controller中就不需要再去写大量的try-catch了，RestControllerAdvice会自动帮助catch,
 * 并匹配相应的ExceptionHandler,然后重新封装异常信息，返回值，统一格式返回给前端。
 */
@Slf4j
@RestControllerAdvice
public class BusinessExceptionHandler extends RuntimeException{


    /**
     * 顶级异常捕获并统一处理，当其他异常无法处理时候选择使用
     * @param e
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ApiResponse handleException(Exception e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_ERROR_KEY_VALUE,  e.toString());
    }


    /**
     * 空指针异常
     * @param e
     * @return
     */
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public ApiResponse handleException(NullPointerException e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_NULLPOINTEREXCEPTION,e.toString());
    }

    /**
     * 数据库操作异常
     * @param e
     * @return
     */
    @ExceptionHandler(SQLException.class)
    @ResponseBody
    public ApiResponse handleException(SQLException e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_DBEXCEPTION,e.toString());
    }
    /**
     * SQL执行异常
     * @param e
     * @return
     */
    @ExceptionHandler(SQLSyntaxErrorException.class)
    @ResponseBody
    public ApiResponse handleException(SQLSyntaxErrorException e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_SQLSYNTAXERROREXCEPTION,e.toString());
    }
    /**
     * 字符串转数值异常
     * @param e
     * @return
     */
    @ExceptionHandler(NumberFormatException.class)
    @ResponseBody
    public ApiResponse handleException(NumberFormatException e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_MESSAGE_CONVERSION_EXCEPTION,e.toString());
    }
    /**
     * 对象强制转换异常
     * @param e
     * @return
     */
    @ExceptionHandler(ClassCastException.class)
    @ResponseBody
    public ApiResponse handleException(ClassCastException e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_CLASSCASTEXCEPTION,e.toString());
    }
    /**
     * 非法参数异常
     * @param e
     * @return
     */
    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseBody
    public ApiResponse handleException(IllegalArgumentException e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_ILLEGALARGUMENTEXCEPTION,e.toString());
    }
    /**
     * 找不到方法异常
     * @param e
     * @return
     */
    @ExceptionHandler(NoSuchMethodException.class)
    @ResponseBody
    public ApiResponse handleException(NoSuchMethodException e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_NOSUCHMETHODEXCEPTION,e.toString());
    }




    /**
     * 方法参数校验
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ApiResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_METHODARGUMENTNOTVALIDEXCEPTION,e.toString());
    }
    /**
     * 运算异常
     * @param e
     * @return
     */
    @ExceptionHandler(ArithmeticException.class)
    @ResponseBody
    public ApiResponse handleException(ArithmeticException e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(BaseError.BI_ARITHMETICEXCEPTION,e.toString());
    }

    /**
     * 自定义异常异常
     * @param e
     * @return
     */
    @ExceptionHandler(MyException.class)
    public ApiResponse handleException(MyException e){
        log.error(e.getMessage(), e);
        return ApiResponse.error(e.getCode(),e.getMessage(),e.getErrorInfo());
    }

}
